home *** CD-ROM | disk | FTP | other *** search
/ MaxiMac 2000 December / MaxiMac 109.iso / Macworld on CD n°109 / Applications (Mac OS X PB) / MacOSX ScreenSavers / Source Code / Paper Airplanes / OpenGLplane.c < prev   
Encoding:
C/C++ Source or Header  |  2000-10-02  |  5.6 KB  |  273 lines  |  [????/????]

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <unistd.h>
  11. #include <math.h>
  12. #include <OpenGL/glu.h>
  13.  
  14. /* Some <math.h> files do not define M_PI... */
  15. #ifndef M_PI
  16. #define M_PI 3.14159265
  17. #endif
  18. #ifndef M_PI_2
  19. #define M_PI_2 1.57079632
  20. #endif
  21.  
  22. GLboolean moving = GL_FALSE;
  23.  
  24. #define MAX_PLANES 9
  25.  
  26. struct {
  27.   float speed;          /* zero speed means not flying */
  28.   GLfloat red, green, blue;
  29.   float theta;
  30.   float x, y, z, angle;
  31. } planes[MAX_PLANES];
  32.  
  33. #define v3f glVertex3f  /* v3f was the short IRIS GL name for
  34.                            glVertex3f */
  35.  
  36. void
  37. draw_plane(void)
  38. {
  39.   GLfloat red, green, blue;
  40.   int i;
  41.  
  42.   glClear(GL_DEPTH_BUFFER_BIT);
  43.   /* paint black to blue smooth shaded polygon for background */
  44.   glDisable(GL_DEPTH_TEST);
  45.   glShadeModel(GL_SMOOTH);
  46.   glBegin(GL_POLYGON);
  47.   glColor3f(0.0, 0.0, 0.0);
  48.   v3f(-20, 20, -19);
  49.   v3f(20, 20, -19);
  50.   glColor3f(0.0, 0.0, 1.0);
  51.   v3f(20, -20, -19);
  52.   v3f(-20, -20, -19);
  53.   glEnd();
  54.   /* paint planes */
  55.   glEnable(GL_DEPTH_TEST);
  56.   glShadeModel(GL_FLAT);
  57.   for (i = 0; i < MAX_PLANES; i++)
  58.     if (planes[i].speed != 0.0) {
  59.       glPushMatrix();
  60.       glTranslatef(planes[i].x, planes[i].y, planes[i].z);
  61.       glRotatef(290.0, 1.0, 0.0, 0.0);
  62.       glRotatef(planes[i].angle, 0.0, 0.0, 1.0);
  63.       glScalef(1.0 / 3.0, 1.0 / 4.0, 1.0 / 4.0);
  64.       glTranslatef(0.0, -4.0, -1.5);
  65.       glBegin(GL_TRIANGLE_STRIP);
  66.       /* left wing */
  67.       v3f(-7.0, 0.0, 2.0);
  68.       v3f(-1.0, 0.0, 3.0);
  69.       glColor3f(red = planes[i].red, green = planes[i].green,
  70.         blue = planes[i].blue);
  71.       v3f(-1.0, 7.0, 3.0);
  72.       /* left side */
  73.       glColor3f(0.6 * red, 0.6 * green, 0.6 * blue);
  74.       v3f(0.0, 0.0, 0.0);
  75.       v3f(0.0, 8.0, 0.0);
  76.       /* right side */
  77.       v3f(1.0, 0.0, 3.0);
  78.       v3f(1.0, 7.0, 3.0);
  79.       /* final tip of right wing */
  80.       glColor3f(red, green, blue);
  81.       v3f(7.0, 0.0, 2.0);
  82.       glEnd();
  83.       glPopMatrix();
  84.     }
  85.   glFlush();
  86. }
  87.  
  88. void
  89. tick_per_plane(int i)
  90. {
  91.   float theta = planes[i].theta += planes[i].speed;
  92.   planes[i].z = -9 + 4 * cos(theta);
  93.   planes[i].x = 4 * sin(2 * theta);
  94.   planes[i].y = sin(theta / 3.4) * 3;
  95.   planes[i].angle = ((atan(2.0) + M_PI_2) * sin(theta) - M_PI_2) * 180 / M_PI;
  96.   if (planes[i].speed < 0.0)
  97.     planes[i].angle += 180;
  98. }
  99.  
  100. void
  101. add_plane(void)
  102. {
  103.   int i;
  104.  
  105.   for (i = 0; i < MAX_PLANES; i++)
  106.     if (planes[i].speed == 0) {
  107.  
  108. #define SET_COLOR(r,g,b) \
  109.     planes[i].red=r; planes[i].green=g; planes[i].blue=b;
  110.  
  111.       switch (random() % 6) {
  112.       case 0:
  113.         SET_COLOR(1.0, 0.0, 0.0);  /* red */
  114.         break;
  115.       case 1:
  116.         SET_COLOR(1.0, 1.0, 1.0);  /* white */
  117.         break;
  118.       case 2:
  119.         SET_COLOR(0.0, 1.0, 0.0);  /* green */
  120.         break;
  121.       case 3:
  122.         SET_COLOR(1.0, 0.0, 1.0);  /* magenta */
  123.         break;
  124.       case 4:
  125.         SET_COLOR(1.0, 1.0, 0.0);  /* yellow */
  126.         break;
  127.       case 5:
  128.         SET_COLOR(0.0, 1.0, 1.0);  /* cyan */
  129.         break;
  130.       }
  131.       planes[i].speed = (random() % 20) * 0.001 + 0.02;
  132.       if (random() & 0x1)
  133.         planes[i].speed *= -1;
  134.       planes[i].theta = ((float) (random() % 257)) * 0.1111;
  135.       tick_per_plane(i);
  136.       return;
  137.     }
  138. }
  139.  
  140. void
  141. remove_plane(void)
  142. {
  143.   int i;
  144.  
  145.   for (i = MAX_PLANES - 1; i >= 0; i--)
  146.     if (planes[i].speed != 0) {
  147.       planes[i].speed = 0;
  148.       return;
  149.     }
  150. }
  151.  
  152. void
  153. tick(void)
  154. {
  155.   int i;
  156.  
  157.   for (i = 0; i < MAX_PLANES; i++)
  158.     if (planes[i].speed != 0.0)
  159.       tick_per_plane(i);
  160. }
  161.  
  162. void
  163. animate_plane(void)
  164. {
  165.   tick();
  166.   draw_plane();
  167. }
  168.  
  169. /*void
  170. visible(int state)
  171. {
  172.   if (state == GLUT_VISIBLE) {
  173.     if (moving)
  174.       glutIdleFunc(animate);
  175.   } else {
  176.     if (moving)
  177.       glutIdleFunc(NULL);
  178.   }
  179. }
  180. */
  181. /* ARGSUSED1 */
  182. void
  183. keyboard(unsigned char ch, int x, int y)
  184. {
  185.   switch (ch) {
  186.   case ' ':
  187.     if (!moving) {
  188.       tick();
  189.     }
  190.     break;
  191.   case 27:             /* ESC */
  192.     exit(0);
  193.     break;
  194.   }
  195. }
  196.  
  197. #define ADD_PLANE    1
  198. #define REMOVE_PLANE    2
  199. #define MOTION_ON    3
  200. #define MOTION_OFF    4
  201. #define QUIT        5
  202.  
  203. /*void
  204. menu(int item)
  205. {
  206.   switch (item) {
  207.   case ADD_PLANE:
  208.     add_plane();
  209.     break;
  210.   case REMOVE_PLANE:
  211.     remove_plane();
  212.     break;
  213.   case MOTION_ON:
  214.     moving = GL_TRUE;
  215.     glutChangeToMenuEntry(3, "Motion off", MOTION_OFF);
  216.     glutIdleFunc(animate);
  217.     break;
  218.   case MOTION_OFF:
  219.     moving = GL_FALSE;
  220.     glutChangeToMenuEntry(3, "Motion", MOTION_ON);
  221.     glutIdleFunc(NULL);
  222.     break;
  223.   case QUIT:
  224.     exit(0);
  225.     break;
  226.   }
  227. }*/
  228.  
  229. void
  230. init_plane(void)
  231. {
  232.  /* setup OpenGL state */
  233.   glClearDepth(1.0);
  234.   glClearColor(0.0, 0.0, 0.0, 0.0);
  235.   glMatrixMode(GL_PROJECTION);
  236.   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 20);
  237.   glMatrixMode(GL_MODELVIEW);
  238.   /* add three initial random planes */
  239.   srandom(getpid());
  240.   add_plane();
  241.   add_plane();
  242.   add_plane();
  243.   return;
  244.  
  245. /*int
  246. main(int argc, char *argv[])
  247. {
  248.   glutInit(&argc, argv);
  249.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
  250.   glutCreateWindow("glutplane");
  251.   glutDisplayFunc(draw);
  252.   glutKeyboardFunc(keyboard);
  253.   glutVisibilityFunc(visible);
  254.   glutCreateMenu(menu);
  255.   glutAddMenuEntry("Add plane", ADD_PLANE);
  256.   glutAddMenuEntry("Remove plane", REMOVE_PLANE);
  257.   glutAddMenuEntry("Motion", MOTION_ON);
  258.   glutAddMenuEntry("Quit", QUIT);
  259.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  260.   glClearDepth(1.0);
  261.   glClearColor(0.0, 0.0, 0.0, 0.0);
  262.   glMatrixMode(GL_PROJECTION);
  263.   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 20);
  264.   glMatrixMode(GL_MODELVIEW);
  265.   srandom(getpid());
  266.   add_plane();
  267.   add_plane();
  268.   add_plane();
  269.   glutMainLoop();
  270.   return 0;             
  271. }
  272. */